/*
 * Copyright (C) 2009 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metalframework.jsf.tag;

import java.io.*;
import java.util.*;

import javax.el.*;
import javax.faces.*;
import javax.faces.component.*;
import javax.faces.model.*;

import org.apache.commons.lang.*;

import com.sun.facelets.*;
import com.sun.facelets.tag.*;

public class EnumSelectItems extends TagHandler {

	private TagAttribute enumClassAttribute;
	private TagAttribute comparatorClassAttribute;
	
	public EnumSelectItems(TagConfig config) {
		super(config);
		this.enumClassAttribute = getRequiredAttribute("class");
		this.comparatorClassAttribute = getAttribute("comparator");
	}
	
	public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException, ELException {
		Enum<?>[] enums = getEnumItems(ctx);
		
		if (parent.getChildCount() < enums.length) {
			for (Enum<?> e : enums) {
				String label = e.toString();
				String value = e.name();
				
				UISelectItem item = new UISelectItem();
				item.setId(ctx.getFacesContext().getViewRoot().createUniqueId());
				item.setItemLabel(label);
				item.setItemValue(value);
				
				SelectItem selectItem = new SelectItem();
				selectItem.setLabel(label);
				selectItem.setValue(e);
				item.setValue(selectItem);
				
				parent.getChildren().add(item);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	protected Enum<?>[] getEnumItems(FaceletContext ctx) {
		String enumClassName = enumClassAttribute.getValue(ctx);
		String comparatorClassName = comparatorClassAttribute == null ? null : comparatorClassAttribute.getValue(ctx);
		
		try {
			Class<? extends Enum<?>> enumClass = ClassUtils.getClass(enumClassName);
			Enum<?>[] enumItems = enumClass.getEnumConstants();
			
			if (comparatorClassName != null) {
				Class<? extends Comparator<? super Enum<?>>> comparatorClass = ClassUtils.getClass(comparatorClassName);
				Comparator<? super Enum<?>> comparator = comparatorClass.newInstance();
				Arrays.sort(enumItems, comparator);
			}
			
			return enumItems;
		} catch (Exception e) {
			throw new FaceletException(e);
		}
	}
}
